"""
日志插件
提供日志记录、查询和管理功能
"""
from datetime import datetime, timedelta
from typing import Dict, Any, List, Optional
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
import json
import os
from pathlib import Path

from plugin_system.base import BasePlugin, PluginInfo, PluginConfig


class LogEntry(BaseModel):
    """日志条目模型"""
    timestamp: datetime
    level: str
    message: str
    source: str
    details: Optional[Dict[str, Any]] = None


class LogQuery(BaseModel):
    """日志查询模型"""
    level: Optional[str] = None
    source: Optional[str] = None
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    limit: int = 100
    offset: int = 0


class LogStats(BaseModel):
    """日志统计模型"""
    total_logs: int
    logs_by_level: Dict[str, int]
    logs_by_source: Dict[str, int]
    recent_logs: List[LogEntry]


class LoggerPlugin(BasePlugin):
    """日志插件"""
    
    def __init__(self):
        super().__init__()
        self.router = APIRouter(prefix="/logger", tags=["logger"])
        self.logs: List[LogEntry] = []
        self.log_file: Optional[Path] = None
        self._setup_routes()
    
    def get_info(self) -> PluginInfo:
        """获取插件信息"""
        return PluginInfo(
            name="logger",
            version="1.0.0",
            description="一个功能完整的日志记录和管理插件",
            author="FastAPI Plugin System",
            homepage="https://github.com/fastapi-plugins",
            dependencies=[],
            tags=["utility", "logger", "monitoring"],
            created_at=datetime.now(),
            updated_at=datetime.now()
        )
    
    def initialize(self) -> bool:
        """初始化插件"""
        try:
            self.info = self.get_info()
            self.config = PluginConfig(
                enabled=True,
                settings={
                    "log_file": "logs/app.log",
                    "max_logs": 10000,
                    "auto_cleanup": True,
                    "cleanup_interval_hours": 24,
                    "log_levels": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
                },
                auto_start=True
            )
            
            # 创建日志目录
            log_dir = Path("logs")
            log_dir.mkdir(exist_ok=True)
            
            # 设置日志文件路径
            self.log_file = Path(self.config.settings["log_file"])
            self.log_file.parent.mkdir(exist_ok=True)
            
            return True
        except Exception as e:
            print(f"日志插件初始化失败: {e}")
            return False
    
    def start(self) -> bool:
        """启动插件"""
        try:
            print("日志插件已启动")
            # 记录启动日志
            self.log("INFO", "日志插件启动成功", "logger")
            return True
        except Exception as e:
            print(f"日志插件启动失败: {e}")
            return False
    
    def stop(self) -> bool:
        """停止插件"""
        try:
            self.log("INFO", "日志插件停止", "logger")
            print("日志插件已停止")
            return True
        except Exception as e:
            print(f"日志插件停止失败: {e}")
            return False
    
    def get_routes(self) -> List[Dict[str, Any]]:
        """获取插件路由"""
        return [
            {
                "path": "/logger/log",
                "methods": ["POST"],
                "description": "记录日志"
            },
            {
                "path": "/logger/logs",
                "methods": ["GET"],
                "description": "查询日志"
            },
            {
                "path": "/logger/stats",
                "methods": ["GET"],
                "description": "获取日志统计"
            },
            {
                "path": "/logger/clear",
                "methods": ["DELETE"],
                "description": "清空日志"
            },
            {
                "path": "/logger/export",
                "methods": ["GET"],
                "description": "导出日志"
            }
        ]
    
    def log(self, level: str, message: str, source: str = "system", details: Optional[Dict[str, Any]] = None) -> None:
        """记录日志"""
        log_entry = LogEntry(
            timestamp=datetime.now(),
            level=level.upper(),
            message=message,
            source=source,
            details=details
        )
        
        # 添加到内存中的日志列表
        self.logs.append(log_entry)
        
        # 写入文件
        if self.log_file:
            try:
                with open(self.log_file, "a", encoding="utf-8") as f:
                    log_line = {
                        "timestamp": log_entry.timestamp.isoformat(),
                        "level": log_entry.level,
                        "message": log_entry.message,
                        "source": log_entry.source,
                        "details": log_entry.details
                    }
                    f.write(json.dumps(log_line, ensure_ascii=False) + "\n")
            except Exception as e:
                print(f"写入日志文件失败: {e}")
        
        # 自动清理旧日志
        self._cleanup_logs()
    
    def _cleanup_logs(self) -> None:
        """清理旧日志"""
        max_logs = self.config.settings.get("max_logs", 10000)
        if len(self.logs) > max_logs:
            # 保留最新的日志
            self.logs = self.logs[-max_logs:]
    
    def query_logs(self, query: LogQuery) -> List[LogEntry]:
        """查询日志"""
        filtered_logs = self.logs
        
        # 按级别过滤
        if query.level:
            filtered_logs = [log for log in filtered_logs if log.level == query.level.upper()]
        
        # 按来源过滤
        if query.source:
            filtered_logs = [log for log in filtered_logs if log.source == query.source]
        
        # 按时间范围过滤
        if query.start_time:
            filtered_logs = [log for log in filtered_logs if log.timestamp >= query.start_time]
        
        if query.end_time:
            filtered_logs = [log for log in filtered_logs if log.timestamp <= query.end_time]
        
        # 排序（最新的在前）
        filtered_logs.sort(key=lambda x: x.timestamp, reverse=True)
        
        # 分页
        start = query.offset
        end = start + query.limit
        return filtered_logs[start:end]
    
    def get_stats(self) -> LogStats:
        """获取日志统计"""
        # 按级别统计
        logs_by_level = {}
        for log in self.logs:
            level = log.level
            logs_by_level[level] = logs_by_level.get(level, 0) + 1
        
        # 按来源统计
        logs_by_source = {}
        for log in self.logs:
            source = log.source
            logs_by_source[source] = logs_by_source.get(source, 0) + 1
        
        # 最近的日志
        recent_logs = sorted(self.logs, key=lambda x: x.timestamp, reverse=True)[:10]
        
        return LogStats(
            total_logs=len(self.logs),
            logs_by_level=logs_by_level,
            logs_by_source=logs_by_source,
            recent_logs=recent_logs
        )
    
    def clear_logs(self) -> None:
        """清空日志"""
        self.logs.clear()
        if self.log_file and self.log_file.exists():
            self.log_file.unlink()
        self.log("INFO", "日志已清空", "logger")
    
    def export_logs(self, format: str = "json") -> str:
        """导出日志"""
        if format.lower() == "json":
            return json.dumps([log.dict() for log in self.logs], ensure_ascii=False, indent=2, default=str)
        elif format.lower() == "text":
            lines = []
            for log in self.logs:
                line = f"[{log.timestamp}] {log.level} - {log.source}: {log.message}"
                if log.details:
                    line += f" - {json.dumps(log.details, ensure_ascii=False)}"
                lines.append(line)
            return "\n".join(lines)
        else:
            raise ValueError("不支持的导出格式")
    
    def _setup_routes(self):
        """设置路由"""
        
        @self.router.post("/log")
        async def add_log(log_data: Dict[str, Any]):
            """记录日志"""
            level = log_data.get("level", "INFO")
            message = log_data.get("message", "")
            source = log_data.get("source", "api")
            details = log_data.get("details")
            
            if not message:
                raise HTTPException(status_code=400, detail="日志消息不能为空")
            
            self.log(level, message, source, details)
            return {"message": "日志记录成功", "timestamp": datetime.now().isoformat()}
        
        @self.router.get("/logs")
        async def get_logs(
            level: Optional[str] = None,
            source: Optional[str] = None,
            start_time: Optional[str] = None,
            end_time: Optional[str] = None,
            limit: int = 100,
            offset: int = 0
        ):
            """查询日志"""
            query = LogQuery(
                level=level,
                source=source,
                limit=limit,
                offset=offset
            )
            
            if start_time:
                try:
                    query.start_time = datetime.fromisoformat(start_time)
                except ValueError:
                    raise HTTPException(status_code=400, detail="无效的开始时间格式")
            
            if end_time:
                try:
                    query.end_time = datetime.fromisoformat(end_time)
                except ValueError:
                    raise HTTPException(status_code=400, detail="无效的结束时间格式")
            
            logs = self.query_logs(query)
            return {
                "logs": [log.dict() for log in logs],
                "total": len(self.logs),
                "count": len(logs)
            }
        
        @self.router.get("/stats")
        async def get_stats():
            """获取日志统计"""
            stats = self.get_stats()
            return stats.dict()
        
        @self.router.delete("/clear")
        async def clear_logs():
            """清空日志"""
            self.clear_logs()
            return {"message": "日志已清空"}
        
        @self.router.get("/export")
        async def export_logs(format: str = "json"):
            """导出日志"""
            try:
                exported_data = self.export_logs(format)
                return {
                    "format": format,
                    "data": exported_data,
                    "count": len(self.logs)
                }
            except ValueError as e:
                raise HTTPException(status_code=400, detail=str(e))
        
        @self.router.get("/levels")
        async def get_log_levels():
            """获取支持的日志级别"""
            return {
                "levels": self.config.settings.get("log_levels", ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"])
            }
        
        @self.router.get("/sources")
        async def get_log_sources():
            """获取所有日志来源"""
            sources = list(set(log.source for log in self.logs))
            return {"sources": sources} 